<!--
  智慧社区管理系统 - 权限分配弹窗
  @author Wu.Liang
  @date 2024-01-01
  @updated 2025-01-27 - 改造权限分配功能，支持完整权限树展示和超级管理员权限保护
-->
<template>
    <el-dialog
        v-model="dialogVisible"
        title="分配权限"
        width="900px"
        :close-on-click-modal="false"
        @close="handleClose"
    >
        <div class="permission-assign">
            <!-- 角色信息 -->
            <div class="role-info" v-if="roleData">
                <el-descriptions :column="2" border>
                    <el-descriptions-item label="角色名称">
                        {{ roleData.roleName }}
                    </el-descriptions-item>
                    <el-descriptions-item label="角色编码">
                        {{ roleData.roleCode }}
                    </el-descriptions-item>
                    <el-descriptions-item label="角色描述" :span="2">
                        {{ roleData.description || '暂无描述' }}
                    </el-descriptions-item>
                </el-descriptions>
                
                <!-- 超级管理员提示 -->
                <el-alert 
                    v-if="isSuperAdminRole"
                    title="超级管理员权限说明" 
                    type="warning" 
                    :closable="false"
                    show-icon
                    class="admin-alert"
                >
                    <template #default>
                        <p>超级管理员的已有权限显示为灰色锁图标，不能取消勾选，只能增加新的权限。</p>
                    </template>
                </el-alert>
            </div>

            <!-- 权限树 -->
            <div class="permission-tree">
                <div class="tree-header">
                    <h3>权限分配</h3>
                    <div class="tree-actions">
                        <el-button size="small" @click="expandAll">全部展开</el-button>
                        <el-button size="small" @click="collapseAll">全部收起</el-button>
                        <el-button 
                            size="small" 
                            @click="selectAll"
                            :disabled="isSuperAdminRole"
                        >
                            全选
                        </el-button>
                        <el-button 
                            size="small" 
                            @click="clearAll"
                            :disabled="isSuperAdminRole"
                        >
                            清空
                        </el-button>
                    </div>
                </div>
                
                <el-tree
                    ref="treeRef"
                    :data="permissionTree"
                    :props="treeProps"
                    :default-checked-keys="checkedKeys"
                    :default-expanded-keys="expandedKeys"
                    show-checkbox
                    node-key="id"
                    :check-strictly="false"
                    @check="handleNodeCheck"
                    v-loading="loading"
                    class="permission-tree-content"
                >
                    <template #default="{ node, data }">
                        <div class="tree-node">
                            <span class="node-icon" :class="getNodeIconClass(data.type)">
                                {{ getNodeIconText(data.type) }}
                            </span>
                            <span class="node-label">{{ data.permissionName }}</span>
                            <el-tag 
                                v-if="data.type" 
                                size="small" 
                                :type="getPermissionTypeTag(data.type)"
                                class="node-type"
                            >
                                {{ getPermissionTypeText(data.type) }}
                            </el-tag>
                            <!-- 超级管理员已有权限标识 -->
                            <span 
                                v-if="isSuperAdminRole && isExistingPermission(data.id)" 
                                class="existing-permission-icon"
                                title="超级管理员已有权限，不可取消"
                            >
                                🔒
                            </span>
                        </div>
                    </template>
                </el-tree>
            </div>
        </div>

        <template #footer>
            <div class="dialog-footer">
                <el-button @click="handleClose">取消</el-button>
                <el-button type="primary" :loading="submitLoading" @click="handleSubmit">
                    保存权限
                </el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, nextTick } from 'vue'
import { ElMessage, type ElTree } from 'element-plus'
import type { RoleInfo, PermissionTree } from '@/api/role'
import { getCompletePermissionTree, getRolePermissions, assignRolePermissions } from '@/api/role'
import { ROLE_CODES } from '@/constants/roles'

// Props
interface Props {
    modelValue: boolean
    roleData?: RoleInfo | null
}

const props = withDefaults(defineProps<Props>(), {
    modelValue: false,
    roleData: null
})

// Emits
const emit = defineEmits<{
    'update:modelValue': [value: boolean]
    'success': []
}>()

// 响应式数据
const treeRef = ref<InstanceType<typeof ElTree>>()
const loading = ref(false)
const submitLoading = ref(false)
const permissionTree = ref<PermissionTree[]>([])
const checkedKeys = ref<number[]>([])
const expandedKeys = ref<number[]>([])
const existingPermissionIds = ref<number[]>([]) // 记录角色已有的权限ID

// 树形配置
const treeProps = {
    children: 'children',
    label: 'permissionName'
}

// 计算属性
const dialogVisible = computed({
    get: () => props.modelValue,
    set: (value) => emit('update:modelValue', value)
})

// 检查是否为超级管理员角色
const isSuperAdminRole = computed(() => {
  return props.roleData?.roleCode === ROLE_CODES.SUPER_ADMIN
})

// 判断权限是否为角色已有权限
const isExistingPermission = (permissionId: number) => {
    return existingPermissionIds.value.includes(permissionId)
}

// 获取权限树
const fetchPermissionTree = async () => {
    try {
        loading.value = true
        const response = await getCompletePermissionTree(1) // 只获取启用的权限
        console.log('完整权限树接口返回数据:', response)
        permissionTree.value = Array.isArray(response.data) ? response.data : []
        
        // 自动展开第一级节点
        if (permissionTree.value.length > 0) {
            expandedKeys.value = permissionTree.value.map(item => item.id)
        }
    } catch (error: any) {
        permissionTree.value = []
        ElMessage.error(`获取权限树失败: ${error.message}` as any)
    } finally {
        loading.value = false
    }
}

// 获取角色权限
const fetchRolePermissions = async () => {
    if (!props.roleData?.id) {
        checkedKeys.value = []
        existingPermissionIds.value = []
        return
    }
    try {
        const response = await getRolePermissions(props.roleData.id)
        const permissionIds = Array.isArray(response.data) ? response.data : []
        checkedKeys.value = [...permissionIds]
        existingPermissionIds.value = [...permissionIds] // 记录已有权限
        
        console.log('角色已有权限:', permissionIds)
    } catch (error: any) {
        checkedKeys.value = []
        existingPermissionIds.value = []
        ElMessage.error(`获取角色权限失败: ${error.message}` as any)
    }
}

// 监听弹窗显示
watch(() => props.modelValue, (visible) => {
    if (visible) {
        fetchPermissionTree()
        fetchRolePermissions()
    }
})

// 处理节点勾选事件
const handleNodeCheck = (data: PermissionTree, checkedInfo: any) => {
    if (isSuperAdminRole.value) {
        // 超级管理员角色，检查是否试图取消已有权限
        const checkedKeys = checkedInfo.checkedKeys
        const halfCheckedKeys = checkedInfo.halfCheckedKeys
        
        // 确保已有权限不被取消
        existingPermissionIds.value.forEach(existingId => {
            if (!checkedKeys.includes(existingId) && !halfCheckedKeys.includes(existingId)) {
                // 如果试图取消已有权限，重新勾选
                nextTick(() => {
                    treeRef.value?.setChecked(existingId, true, false)
                })
            }
        })
    }
}

// 展开所有节点
const expandAll = () => {
    const allKeys = getAllPermissionIds(permissionTree.value)
    expandedKeys.value = allKeys
}

// 收起所有节点
const collapseAll = () => {
    expandedKeys.value = []
}

// 全选
const selectAll = () => {
    if (isSuperAdminRole.value) return
    
    const allKeys = getAllPermissionIds(permissionTree.value)
    checkedKeys.value = allKeys
    treeRef.value?.setCheckedKeys(allKeys)
}

// 清空
const clearAll = () => {
    if (isSuperAdminRole.value) return
    
    checkedKeys.value = []
    treeRef.value?.setCheckedKeys([])
}

// 获取所有权限ID（递归）
const getAllPermissionIds = (permissions: PermissionTree[]): number[] => {
    const ids: number[] = []
    permissions.forEach(permission => {
        ids.push(permission.id)
        if (permission.children && permission.children.length > 0) {
            ids.push(...getAllPermissionIds(permission.children))
        }
    })
    return ids
}

// 获取节点图标文本
const getNodeIconText = (type: number) => {
    switch (type) {
        case 1: return '📁'
        case 2: return '🔘'
        case 3: return '🔗'
        default: return '📄'
    }
}

// 获取节点图标样式
const getNodeIconClass = (type: number) => {
    switch (type) {
        case 1: return 'icon-menu'
        case 2: return 'icon-button'
        case 3: return 'icon-api'
        default: return 'icon-default'
    }
}

// 获取权限类型标签样式
const getPermissionTypeTag = (type: number) => {
    switch (type) {
        case 1: return 'primary'
        case 2: return 'success'
        case 3: return 'warning'
        default: return 'info'
    }
}

// 获取权限类型文本
const getPermissionTypeText = (type: number) => {
    switch (type) {
        case 1: return '菜单'
        case 2: return '按钮'
        case 3: return '接口'
        default: return '未知'
    }
}

// 提交权限分配
const handleSubmit = async () => {
    if (!props.roleData?.id) {
        ElMessage.error('角色信息不存在' as any)
        return
    }
    
    try {
        submitLoading.value = true
        
        // 获取选中的权限ID
        const checkedNodes = treeRef.value?.getCheckedNodes() || []
        const halfCheckedNodes = treeRef.value?.getHalfCheckedNodes() || []
        
        // 合并完全选中和半选中的权限ID
        const allCheckedIds = [
            ...checkedNodes.map(node => node.id),
            ...halfCheckedNodes.map(node => node.id)
        ]
        
        console.log('提交的权限ID:', allCheckedIds)
        console.log('原有权限ID:', existingPermissionIds.value)
        
        // 第1步：前端判断权限是否发生变化
        const hasChanged = checkPermissionChanged(allCheckedIds, existingPermissionIds.value)
        if (!hasChanged) {
            ElMessage.success('权限未发生变化，无需更新' as any)
            emit('success')
            handleClose()
            return
        }
        
        const response = await assignRolePermissions(props.roleData.id, allCheckedIds)
        
        if (response) {
            ElMessage.success('权限分配成功' as any)
            emit('success')
            handleClose()
        } else {
            ElMessage.error('权限分配失败' as any)
        }
    } catch (error: any) {
        ElMessage.error(`权限分配失败: ${error.message}` as any)
    } finally {
        submitLoading.value = false
    }
}

// 检查权限是否发生变化
const checkPermissionChanged = (newIds: number[], oldIds: number[]): boolean => {
    if (newIds.length !== oldIds.length) {
        return true
    }
    
    // 排序后比较
    const sortedNewIds = [...newIds].sort((a, b) => a - b)
    const sortedOldIds = [...oldIds].sort((a, b) => a - b)
    
    for (let i = 0; i < sortedNewIds.length; i++) {
        if (sortedNewIds[i] !== sortedOldIds[i]) {
            return true
        }
    }
    
    return false
}

// 关闭弹窗
const handleClose = () => {
    dialogVisible.value = false
    permissionTree.value = []
    checkedKeys.value = []
    expandedKeys.value = []
    existingPermissionIds.value = []
}
</script>

<style scoped>
.permission-assign {
    max-height: 600px;
    overflow-y: auto;
}

.role-info {
    margin-bottom: 20px;
}

.admin-alert {
    margin-top: 10px;
}

.permission-tree {
    border: 1px solid #e4e7ed;
    border-radius: 4px;
}

.tree-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    background-color: #f5f7fa;
    border-bottom: 1px solid #e4e7ed;
}

.tree-header h3 {
    margin: 0;
    font-size: 16px;
    color: #303133;
}

.tree-actions {
    display: flex;
    gap: 8px;
}

.permission-tree-content {
    padding: 16px;
    max-height: 400px;
    overflow-y: auto;
}

.tree-node {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
}

.node-icon {
    font-size: 16px;
    width: 20px;
    text-align: center;
}

.icon-menu {
    color: #409eff;
}

.icon-button {
    color: #67c23a;
}

.icon-api {
    color: #e6a23c;
}

.icon-default {
    color: #909399;
}

.node-label {
    flex: 1;
    font-size: 14px;
    color: #303133;
}

.node-type {
    font-size: 12px;
}

.existing-permission-icon {
    font-size: 14px;
    color: #909399;
    cursor: help;
}

.dialog-footer {
    text-align: right;
}

/* 超级管理员权限特殊样式 */
:deep(.el-tree-node.is-disabled .el-tree-node__content) {
    background-color: #f5f7fa;
}

:deep(.el-tree-node.is-disabled .el-checkbox) {
    opacity: 0.6;
}

:deep(.el-tree-node.is-disabled .el-checkbox.is-checked .el-checkbox__inner) {
    background-color: #909399;
    border-color: #909399;
}
</style> 